package com.lsbc.pay.common;

import java.io.Serializable;

/**
 * 页面json响应时，统一响应的参数
 * 
 * @author yiyang 
 *
 * @date 2019年8月7日
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public class ApiResponse<T> implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7467991410407090791L;
	protected int code;
	protected String msg;
	protected T data;

	/**
	 * Status code (200) indicating the request succeeded normally.
	 */
	public static final int SC_OK = 0;

	/**
	 * Status code (400) indicating the request sent by the client was
	 * syntactically incorrect.
	 */

	public static final int SC_BAD_REQUEST = 400;

	/**
	 * Status code (403) indicating the server understood the request but
	 * refused to fulfill it.
	 */

	public static final int SC_FORBIDDEN = 403;
	
	/**
	 * 重复请求
	 */
	public static final int SC_REPEAT = 501;

	/**
	 * Status code (500) indicating an error inside the HTTP server which
	 * prevented it from fulfilling the request.
	 */

	public static final int SC_INTERNAL_SERVER_ERROR = 500;

	/**
	 * Singleton instance the success is true,status is SC_OK.
	 * <p>
	 * please do not modify this instance properties.
	 *
	 * @see #ok()
	 */

	public static final ApiResponse OK = ok();

	/**
	 * Singleton instance the success is false,status is
	 * SC_INTERNAL_SERVER_ERROR.
	 * <p>
	 * please do not modify this instance properties.
	 */

	public static final ApiResponse ERROR = fail(SC_INTERNAL_SERVER_ERROR);

	/**
	 * Singleton instance the success is false,status is SC_FORBIDDEN.
	 * <p>
	 * please do not modify this instance properties.
	 */
	public static final ApiResponse FORBIDDEN = fail(SC_FORBIDDEN);

	/**
	 * Singleton instance the success is false,status is SC_BAD_REQUEST.
	 * <p>
	 * please do not modify this instance properties.
	 */
	public static final ApiResponse FAIL = fail(SC_BAD_REQUEST);
	
	public static final ApiResponse NULL = fail(SC_OK);

	public ApiResponse(int code, String msg, T content) {
		this.code = code;
		this.msg = msg;
		this.data = content;

	}
	
	public ApiResponse() {
		
	}

	public ApiResponse(int code) {
		this(code, null, null);
	}

	public static final <T> ApiResponse of(int code, String msg) {
		return new ApiResponse(code, msg, null);
	}

	public static final <T> ApiResponse of(int code, String msg, T record) {
		return new ApiResponse(code, msg, record);
	}

	public static final <T> ApiResponse of(int code) {
		return new ApiResponse(code);
	}

	/**
	 * create instance the success is true,status is SC_OK(200)
	 *
	 * @see #SC_OK
	 **/
	private static final ApiResponse ok() {
		return of(SC_OK);
	}

	/**
	 * create instance the success is true,status is SC_OK(200)
	 *
	 * @param records
	 * @see #SC_OK
	 **/
	public static final <T> ApiResponse ok(T records) {
		ApiResponse apiResponse = ok();

		if (records != null) {
			apiResponse.data = records;
		}
		return apiResponse;
	}

	/**
	 * create instance the success is false,status is
	 * SC_INTERNAL_SERVER_ERROR(500)
	 *
	 * @see #SC_INTERNAL_SERVER_ERROR
	 **/
	public static final ApiResponse error(String value) {
		return fail(SC_INTERNAL_SERVER_ERROR).msg(value);
	}

	public static final ApiResponse error(int code, String value) {
		return fail(code).msg(value);
	}

	/**
	 * create instance the success is false,status is SC_BAD_REQUEST(400) add a
	 * message,Key can not be null
	 *
	 * @param value
	 * @see #SC_BAD_REQUEST
	 **/
	public static final ApiResponse fail(String value) {
		return fail(SC_BAD_REQUEST).msg(value);
	}

	/**
	 * create instance the success is false,status is SC_FORBIDDEN(403)
	 *
	 * @param value
	 * @see #SC_BAD_REQUEST
	 **/
	public static final ApiResponse forbidden(String value) {
		return fail(SC_FORBIDDEN).msg(value);
	}

	public static final ApiResponse forbidden() {
		return fail(SC_FORBIDDEN);
	}

	/**
	 * create instance the success is false
	 *
	 * @param status
	 * @see #of
	 **/
	private static final ApiResponse fail(int status) {
		return of(status);
	}

	/**
	 * add a message,Key can not be null
	 *
	 * @param value
	 **/
	public ApiResponse msg(String value) {
		this.msg = value;
		return this;
	}

	public int getCode() {
		return code;
	}

	public String getMsg() {
		return msg;
	}

	public T getData() {
		return data;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public void setData(T data) {
		this.data = data;
	}

	@Override
	public String toString() {
		final StringBuffer sb = new StringBuffer("ApiResponse{");
		sb.append("data=").append(data);
		sb.append(", code=").append(code);
		sb.append(", msg='").append(msg).append('\'');
		sb.append('}');
		return sb.toString();
	}
}
